from flask import render_template, current_app, session, request, jsonify, g, abort

from info import constants
from info.models import User, News, Category
from info.utils.common import user_login_data
from info.utils.response_code import RET
from . import index_blue


# 使用蓝图注册路由
@index_blue.route("/")
@user_login_data
def index():
    """
    1、读取用户id，如存在，渲染主页，不存在，忽略
    2、选择出对应用户对象
    3、利用用户的to_dict将用户对象的属性转换为字典的键值对，作为参数返回
    :return:
    """
    # 通过装饰器及g变量来查询登录状态
    user = g.user

    news_list = None
    # 查询所有新闻信息，返回一个新闻列表
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)
    # 遍历该列表,三元表达式，通过to_base_dict方法得到字典，存入新列表中
    news_dict_list = []
    for new in news_list if news_list else []:
        news_dict_list.append(new.to_basic_dict())
    """
    主页新闻分类展示
    1、查询全部分类
    2、数据处理
    3、返回数据
    """
    categories = Category.query.all()
    category_list = [category.to_dict() for category in categories]

    data_dict = {
        "user": user.to_dict() if user else None,
        "news_dict_list": news_dict_list,
        "category_list": category_list
    }
    return render_template("news/index.html", data=data_dict)


# 添加静态访问网站标签小图标
@index_blue.route("/favicon.ico")
def favicon():
    return current_app.send_static_file("news/favicon.ico")


# 新闻列表数据
@index_blue.route("/newslist")
def news_list():
    """
    1、获取参数 cid , page,per_page
    2、校验参数
    3、根据cid 查询数据库中news对象
    4、处理数据
    5、返回数据
    :return:
    """
    # 1、获取参数，get请求
    args_dict = request.args
    category_id = args_dict.get("cid", 1)
    page = args_dict.get("page", 1)
    per_page = args_dict.get("per_page", constants.HOME_PAGE_MAX_NEWS)

    # 2、校验参数
    try:
        category_id = int(category_id)
        page = int(page)
        per_page = int(per_page)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3、查询数据并分页，如果cid不为1，表示获取其他分类的新闻信息，需要根据cid添加过滤条件，选择哪个分类下的最新的信息，默认的是最新，只需要按照新闻创建时间进行排序展示即可
    filter_list = [News.status == 0]
    if category_id != 1:
        filter_list.append(News.category_id == category_id)

    try:
        paginate = News.query.filter(*filter_list).order_by(News.create_time.desc()).paginate(page=page,
                                                                                              per_page=per_page,
                                                                                              error_out=False)
        # 筛选后当前分类的最新新闻
        news_items = paginate.items
        # 筛选后当前分类新闻总页数
        total_pages = paginate.pages
        current_page = paginate.page
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据查询失败")

    # 4、将筛选后的新闻对象处理为字典后返回给前端
    news_li = [new.to_basic_dict() for new in news_items]

    # 5、返回数据
    return jsonify(errno=RET.OK, errmsg="获取新闻数据成功", cid=category_id, totalPage=total_pages,
                   cur_page=current_page, newsList=news_li)
